﻿using SS.WPF.Framework.Display.Progress;

namespace SS.WPF.Framework.Display.Dialog
{
    using System;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Controls;

    public partial class DialogManager
    {
        private class WorkerUserState
        {
            internal Window Owner;
            internal ProgressDialog Dialog;
            internal Button Sender;
            internal Action OnCompleted;
        }

        public void ShowProgressDialog(string caption, string message, DoWorkEventHandler job,
            object owner, object sender, Action onCmpleted = null)
        {
            var progressDialog = new ProgressDialog
            {
                Title = "Title",
                Caption = caption,
                Message = message,
                TimeRemaining = "TimeRemaining",
                CancelMessage = "CancelMessage",
                EstimatesTimeRemaining = true,
                HasMinimizeButton = false,
                TotalValue = 100,
                IsModal = true
            };

            RunWorker(new WorkerUserState
            {
                Owner = (Window)owner,
                Dialog = progressDialog,
                Sender = (Button)sender,
                OnCompleted = onCmpleted
            }, job);
        }

        private static void RunWorker(WorkerUserState userState, DoWorkEventHandler job)
        {
            userState.Sender.IsEnabled = false;
            userState.Dialog.ShowDialog(userState.Owner);

            var worker = new BackgroundWorker
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true,
            };

            worker.DoWork += job;
            worker.ProgressChanged += OnProgressChanged;
            worker.RunWorkerCompleted += OnWorkerCompleted;

            worker.RunWorkerAsync(userState);
        }

        private static void OnProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            var worker = (BackgroundWorker)sender;
            var userState = (WorkerUserState)e.UserState;

            // Update progress bar
            userState.Dialog.Value = (ulong)e.ProgressPercentage;

            // Cancel the operation if Cancel button has been pressed
            if (userState.Dialog.IsCancelled)
            {
                worker.CancelAsync();
                userState.Dialog.CloseDialog();
                userState.Sender.IsEnabled = true;
            }
        }

        private static void OnWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
                return;
            }

            var worker = (BackgroundWorker)sender;
            var userState = (WorkerUserState)e.Result;

            // Update UI
            if (userState != null)
            {
                userState.Dialog.CloseDialog();
                userState.Sender.IsEnabled = true;
                if (userState.OnCompleted != null && !userState.Dialog.IsCancelled)
                {
                    userState.OnCompleted();
                }
            }
        }
    }
}
